//
//  Query.m
//  PezMonkey
//
//  Created by Spence DiNicolantonio on 12/26/09.
//  Copyright 2009 Necrosoft. All rights reserved.
//

#import "Query.h"

#define kQueryLineWidth 8


@implementation Query

@synthesize querySegShape;

- (NSString *)demoName {
	return @"Query";
}

- (void) start {
	// create space
	self.space = [PMSpace space];
	[space setSubSteps:3];
	[space setElasticIterations:0];
	[space setIterations:1];
	[space setActiveHashSize:999 cellDimension:40];
	[space setStaticHashSize:2999 cellDimension:30];
	
	// create shared static body
	PMBody *staticBody = [PMBody staticBody];
	
	
	PMBody *body;
	PMShape *shape;
	
	
	// define fat segment attributes
	PMFloat segMass = 1.0;
	PMFloat segLength = 100.0;
	PMFloat segWidth = 40.0;
	PMVect segStart = PMVectMake(-segLength/2, 0);
	PMVect segEnd = PMVectMake(segLength/2, 0);
	PMFloat segMoment = PMMomentForSegment(segMass, segStart, segEnd);
	
	// create fat segment body
	body = [PMBody bodyWithMass:segMass 
						 moment:segMoment];
	[body setPosition:PMVectMake(0, 100)];
	[space addBody:body];
	
	// create fat segment shape
	shape = [PMSegmentShape segmentShapeWithBody:body 
										   start:segStart 
											 end:segEnd
										   width:segWidth];
	[space addShape:shape];
	
	
	// create static segment
	shape = [PMSegmentShape segmentShapeWithBody:staticBody 
										   start:PMVectMake(0, 300) 
											 end:PMVectMake(300, 0)];
	[space addStaticShape:shape];
	
	
	// define pentagon attributes
	PMFloat pentMass = 1.0;
	NSUInteger vertCount = 5;
	PMVect verts[vertCount];
	for (int i=0; i<vertCount; i++) {
		PMFloat angle = -2*M_PI*i / (PMFloat)vertCount;
		verts[i] = PMVectMake(30*cos(angle), 30*sin(angle));
	}
	PMFloat pentMoment = PMMomentForPolygon(pentMass, verts, vertCount, PMVectZero);
	
	// create pentagon body
	body = [PMBody bodyWithMass:pentMass 
						 moment:pentMoment];
	[body setPosition:PMVectMake(50, 50)];
	[space addBody:body];
	
	// create pentagon shape
	shape = [PMPolygonShape polygonShapeWithBody:body 
										vertices:verts
									   vertCount:vertCount];
	[space addShape:shape];
	
	
	// define circle attributes
	PMFloat circMass = 1.0;
	PMFloat circRadius = 20.0;
	PMFloat circMoment = PMMomentForCircle(circMass, 0, circRadius, PMVectZero);
	
	// create circle body
	body = [PMBody bodyWithMass:circMass 
						 moment:circMoment];
	[body setPosition:PMVectMake(100, 100)];
	[space addBody:body];
	
	// create circle shape
	shape = [PMCircleShape circleShapeWithBody:body 
										radius:circRadius];
	[space addShape:shape];
	
	
	// add non-collidable segment shape to provide drawing of query line
	self.querySegShape = [PMSegmentShape segmentShapeWithBody:staticBody 
														start:PMVectZero 
														  end:PMVectMake(100, 0)
														width:kQueryLineWidth];
	[querySegShape setLayers:PMLayerMaskNone];
	[space addShape:querySegShape];
}

- (void)update:(NSTimeInterval)deltaT {
	// define query segment
	PMSegment querySegment = PMSegmentMake(PMVectZero, mousePoint);
	PMVect end = mousePoint;
	
	// create info string
	NSString *infoString = [NSString stringWithFormat:@"Query: Dist(%f) Point%@\n", 
							PMSegmentLength(querySegment), PMVectToString(end)];
	
	// check for segment collision
	PMSegmentCollisionInfo info;
	if ([space shapeOnSegment:querySegment info:&info]) {
		
		// update segment end point
		end = PMSegmentCollisionHitPoint(info);
		
		// update info string
		infoString = [NSString stringWithFormat:@"%@Segment Query: Dist(%f) Normal%@",
					  infoString, 
					  PMSegmentCollisionHitDistance(info), 
					  PMVectToString(info.normal)];
	} else {
		// update info string
		infoString = [NSString stringWithFormat:@"%@Segment Query: (none)", infoString];
	}
	
	// update query segment shape endpoint
	[querySegShape setEnd:end];
	
	// update message
	NSValue *value = [NSValue valueWithPoint:NSMakePoint(-300, -210)];
	[strings setObject:infoString 
				forKey:value];
}


#pragma mark -
#pragma mark Dealloc

- (void)dealloc {
	[querySegShape release];
	[super dealloc];
}

@end
